package edu.pku.sei.transformation.qvt.engine.modelmorf;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import edu.pku.sei.transformation.editor.model.AtomicTransformation;
import edu.pku.sei.transformation.editor.model.MetaModel;
import edu.pku.sei.transformation.editor.model.ModelType;
import edu.pku.sei.transformation.editor.model.TypedModel;
import edu.pku.sei.transformation.editor.model.execution.Pin;
import edu.pku.sei.transformation.editor.model.execution.TransformationExecution;
import edu.pku.sei.transformation.engine.EngineExtraData;
import edu.pku.sei.transformation.engine.IEngineAdapter;
import edu.pku.sei.transformation.engine.IEngineRunner;
import edu.pku.sei.transformation.execution.ExecutionEnviroment;
import edu.pku.sei.transformation.qvt.adapter.standardqvt.TransformationAdapter;
import edu.pku.sei.transformation.qvt.codegen.QVTGenerator;

public class ModelMorfAdapter implements IEngineAdapter {

	@Override
	public IEngineRunner getRunner(TransformationExecution execution,
			ExecutionEnviroment env) throws Exception {
		ModelMorfRunner runner = new ModelMorfRunner();
		if (!(execution.getTransformation() instanceof AtomicTransformation)) {
			throw new Exception("not support composite transformation");
		}

		TypedModel target = execution.getDirection();
		runner.targetDomain = target.getName();
		if (target == null) {
			throw new Exception("not define target");
		}
		for (TypedModel typedModel : execution.getTransformation()
				.getTypedModel()) {
			ModelType modelType = (ModelType) typedModel.getType();
			MetaModel metaModel = (MetaModel) modelType.getType();
			File metaModelFile = new File(metaModel.getFilePath().trim())
					.getAbsoluteFile();
			runner.metaModel.put(modelType.getName(), metaModelFile);

		}

		for (Pin pin : execution.getActualParameters()) {
			String path = env.getPath(pin);
			if (path != null) {
				File modelFile = new File(path.trim()).getAbsoluteFile();
				//System.out.println(path+" "+modelFile.getAbsolutePath());
				runner.model.put(pin.getFormalParameter().getName(), modelFile);
			}
		}
		// ModelMorfExtraData extradata = (ModelMorfExtraData)
		// execution.getExtraData();
		File qvtfile;
		qvtfile = new File(execution.getWorkDir()+"\\temp\\" + execution.getTransformation().getName()
				+ ".qvt");
		// if (extradata.getQvtFileName() != null &&
		// !extradata.getQvtFileName().equals("")) {
		// qvtfile = new
		// File("temp\\"+extradata.getQvtFileName()).getAbsoluteFile();
		// } else {
		// qvtfile = new
		// File("temp\\"+execution.getTransformation().getName()+".qvt").getAbsoluteFile();
		// }

		runner.qvtSpecificationFile = qvtfile;
		QVTGenerator gen = new QVTGenerator();
		String rule = gen.generate(new TransformationAdapter(
				(AtomicTransformation) execution.getTransformation()));
		FileWriter fw;
		try {
			fw = new FileWriter(runner.qvtSpecificationFile);
			fw.write(rule, 0, rule.length());
			fw.flush();
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		runner.executionMode = execution.getModeString();
		runner.transformationName = execution.getTransformation().getName();

		return runner;
	}

	@Override
	public EngineExtraData getExtraData(EngineExtraData oringin) {
		return new ModelMorfExtraData(oringin);
	}

	@Override
	public String getID() {
		return "ModelMorf";
	}
}
